using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using cframework;
using System.ComponentModel;
using Newtonsoft.Json;
using System.Net;
using System.IO;

namespace cframework
{
    [EssentialTool("node", "https://nodejs.org")]
    [EssentialTool("npm", "https://nodejs.org")]
    [CreateAssetMenu(menuName = "cframework/FileSystemUtil_Supabase")]
    public class FileSystemUtil_Supabase : FileSystemUtil
    {
        [Essential]
        public string projectUrl;
        [Essential]
        public string apiKey;
        [Essential]
        public string bucket;

        static bool installed = false;

        public bool TransmitFile(bool upload, string srcPath, string destPath, bool overwrite, string bucket, string projectUrl, string apiKey)
        {
            //var projectPath = System.IO.Path.GetDirectoryName(Application.dataPath);


            MonoScript script = MonoScript.FromScriptableObject(this);
            string path = AssetDatabase.GetAssetPath(script);
            path = System.IO.Path.GetFullPath(path);
            string shScriptDir = System.IO.Path.GetDirectoryName(path) + "/supabase_storage~";

            if(!installed)
            {
                //var bashPath = DeviceToolPathSetting.GetSystemToolPath("bash");
                var npmPath = DeviceToolPathSetting.GetSystemToolPath("npm");
                if (string.IsNullOrEmpty(npmPath))
                {
                    throw new System.Exception("npm not found");
                }

                if(Application.platform == RuntimePlatform.WindowsEditor)
                {
                    npmPath = DeviceToolPathSetting.GetSystemToolPath("npm.cmd");
                    if (string.IsNullOrEmpty(npmPath))
                    {
                        throw new System.Exception("npm.cmd not found");
                    }
                }

                var param = $"install";
                var ret = CommandLineTool.RunCommand2(npmPath, " " + param, shScriptDir);

                if (ret.ExitCode != 0)
                {
                    Debug.LogError(ret.ExitCode);
                    Debug.LogError(ret.StdOut);
                    Debug.LogError(ret.StdErr);

                    throw new System.Exception("npm install failed");
                }
                else
                {
                    installed = true;
                }
                
            }

            {
                var nodePath = DeviceToolPathSetting.GetSystemToolPath("node");
                if (string.IsNullOrEmpty(nodePath))
                {
                    throw new System.Exception("node not found");
                }

                var param = $"supabase_storage.js {upload} {srcPath} {destPath} {overwrite} {bucket} {projectUrl} {apiKey}";
                var ret = CommandLineTool.RunCommand2(nodePath, param, shScriptDir);

                if (ret.ExitCode != 0)
                {
                    Debug.LogError(ret.ExitCode);
                    Debug.LogError(ret.StdOut);
                    Debug.LogError(ret.StdErr);
                }
                return ret.ExitCode == 0;
            }
        }

        public override string GetDownloadUrl()
        {
            return $"{projectUrl}/storage/v1/object/public/{bucket}";
        }

        public override bool Upload(string srcPath, string destPath)
        {
            if (System.IO.File.Exists(srcPath))
            {
                if (!TransmitFile(true, srcPath, destPath, true, bucket, projectUrl, apiKey))
                {
                    return false;
                }
            }
            else
            {
                string[] paths = System.IO.Directory.GetFiles(srcPath, "*", System.IO.SearchOption.AllDirectories);
                foreach (var p in paths)
                {
                    var q = p.Replace("\\", "/").Replace(srcPath + "/", "");
                    if (!Upload(p, $"{destPath}/{q}"))
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        public override bool WriteAllText(string path, string text)
        {
            var tempFilePath = System.IO.Path.GetTempFileName();
            System.IO.File.WriteAllText(tempFilePath, text);

            if (!TransmitFile(true, tempFilePath, path, true, bucket, projectUrl, apiKey))
            {
                //throw new System.Exception("WriteAllText to supabase failed: " + path);

                return false;
            }

            return true;
        }

        public override string ReadAllText(string path)
        {
            var tempFilePath = System.IO.Path.GetTempFileName();
            if (!TransmitFile(false, path, tempFilePath, true, bucket, projectUrl, apiKey))
            {
                //throw new System.Exception("ReadAllText from supabase failed: " + path);
                return null;
            }
            return System.IO.File.ReadAllText(tempFilePath);
        }
    }
}

//using System.Collections;
//using System.Collections.Generic;
//using UnityEngine;
//using UnityEditor;
//using cframework;
//using System.ComponentModel;
//using Newtonsoft.Json;
//using System.Net;
//using System.IO;

//namespace cframework
//{
//    [EssentialTool("python3", "https://www.python.org/")]
//    [EssentialTool("supabase", "https://supabase.com/docs/reference/python/introduction?queryGroups=platform&platform=pip", ToolType.python)]
//    [CreateAssetMenu(menuName = "cframework/FileSystemUtil_Supabase")]
//    public class FileSystemUtil_Supabase : FileSystemUtil
//    {
//        [Essential]
//        public string projectUrl;
//        [Essential]
//        public string apiKey;
//        [Essential]
//        public string bucket;

//        public bool TransmitFile(bool upload, string srcPath, string destPath, bool overwrite, string bucket, string projectUrl, string apiKey)
//        {
//            var pythonPath = DeviceToolPathSetting.GetSystemToolPath("python3");
//            if (string.IsNullOrEmpty(pythonPath))
//            {
//                throw new System.Exception("python3 not found");
//            }

//            //var projectPath = System.IO.Path.GetDirectoryName(Application.dataPath);


//            MonoScript script = MonoScript.FromScriptableObject(this);
//            string path = AssetDatabase.GetAssetPath(script);
//            path = System.IO.Path.GetFullPath(path);
//            string shScriptDir = System.IO.Path.GetDirectoryName(path);

//            var param = $"supabase_storage.py {upload} {srcPath} {destPath} {overwrite} {bucket} {projectUrl} {apiKey}";
//            var ret = CommandLineTool.RunCommand2(pythonPath, param, shScriptDir);

//            if(ret.ExitCode != 0)
//            {
//                Debug.LogError(ret.ExitCode);
//                Debug.LogError(ret.StdOut);
//                Debug.LogError(ret.StdErr);
//            }
//            return ret.ExitCode == 0;
//        }

//        public override string GetDownloadUrl()
//        {
//            return $"{projectUrl}/storage/v1/object/public/{bucket}";
//        }

//        public override bool Upload(string srcPath, string destPath)
//        {
//            if (System.IO.File.Exists(srcPath))
//            {
//                if(!TransmitFile(true, srcPath, destPath, true, bucket, projectUrl, apiKey))
//                {
//                    return false;
//                }
//            }
//            else
//            {
//                string[] paths = System.IO.Directory.GetFiles(srcPath, "*", System.IO.SearchOption.AllDirectories);
//                foreach (var p in paths)
//                {
//                    var q = p.Replace("\\", "/").Replace(srcPath + "/", "");
//                    if(!Upload(p, $"{destPath}/{q}"))
//                    {
//                        return false;
//                    }
//                }
//            }
//            return true;
//        }

//        public override bool WriteAllText(string path, string text)
//        {
//            var tempFilePath = System.IO.Path.GetTempFileName();
//            System.IO.File.WriteAllText(tempFilePath, text);

//            if(!TransmitFile(true, tempFilePath, path, true, bucket, projectUrl, apiKey))
//            {
//                //throw new System.Exception("WriteAllText to supabase failed: " + path);

//                return false;
//            }

//            return true;
//        }

//        public override string ReadAllText(string path)
//        {
//            var tempFilePath = System.IO.Path.GetTempFileName();
//            if(!TransmitFile(false, path, tempFilePath, true, bucket, projectUrl, apiKey))
//            {
//                //throw new System.Exception("ReadAllText from supabase failed: " + path);
//                return null;
//            }
//            return System.IO.File.ReadAllText(tempFilePath);
//        }
//    }
//}